Tip: Use the Ctrl-Opt-I keyboard shortcut to insert a code chunk into your Markdown document.

Load packages

library(sf)
library(ggplot2)
library(spData)
library(tmap)
library(magick)

Look at data

head(urban_agglomerations)
## Simple feature collection with 6 features and 9 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: -74.00366 ymin: 34.67583 xmax: 139.6917 ymax: 55.755
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
## # A tibble: 6 x 10
##   index  year rank_order country_code country_or_area          city_code
##   <dbl> <dbl>      <dbl>        <dbl> <chr>                        <dbl>
## 1     1  1950          1          840 United States of America     23083
## 2     2  1950          2          392 Japan                        21671
## 3     3  1950          3          826 United Kingdom               22860
## 4     4  1950          4          392 Japan                       206459
## 5     5  1950          5          250 France                       20985
## 6     6  1950          6          643 Russian Federation           22299
## # ... with 4 more variables: urban_agglomeration <chr>, note <chr>,
## #   population_millions <dbl>, geometry <POINT [°]>
str(urban_agglomerations)
## Classes 'sf', 'tbl_df', 'tbl' and 'data.frame':  510 obs. of  10 variables:
##  $ index              : num  1 2 3 4 5 6 7 8 9 10 ...
##  $ year               : num  1950 1950 1950 1950 1950 1950 1950 1950 1950 1950 ...
##  $ rank_order         : num  1 2 3 4 5 6 7 8 9 10 ...
##  $ country_code       : num  840 392 826 392 250 643 32 840 356 156 ...
##  $ country_or_area    : chr  "United States of America" "Japan" "United Kingdom" "Japan" ...
##  $ city_code          : num  23083 21671 22860 206459 20985 ...
##  $ urban_agglomeration: chr  "New York-Newark" "Tokyo" "London" "Kinki M.M.A. (Osaka)" ...
##  $ note               : chr  "…" "1" "2" "3" ...
##  $ population_millions: num  12.34 11.27 8.36 7.01 6.28 ...
##  $ geometry           :sfc_POINT of length 510; first list element: Classes 'XY', 'POINT', 'sfg'  num [1:2] -74 40.7
##  - attr(*, "sf_column")= chr "geometry"
##  - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA NA
##   ..- attr(*, "names")= chr  "Index" "Year" "Rank order" "Country code" ...
names(urban_agglomerations)
##  [1] "index"               "year"                "rank_order"         
##  [4] "country_code"        "country_or_area"     "city_code"          
##  [7] "urban_agglomeration" "note"                "population_millions"
## [10] "geometry"
tail(urban_agglomerations)
## Simple feature collection with 6 features and 9 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: -118.2417 ymin: -12.04318 xmax: 114.0634 ymax: 34.03166
## epsg (SRID):    4326
## proj4string:    +proj=longlat +datum=WGS84 +no_defs
## # A tibble: 6 x 10
##   index  year rank_order country_code country_or_area          city_code
##   <dbl> <dbl>      <dbl>        <dbl> <chr>                        <dbl>
## 1   505  2030         25          360 Indonesia                    21454
## 2   506  2030         26          840 United States of America     23052
## 3   507  2030         27          586 Pakistan                     22046
## 4   508  2030         28          356 India                        21275
## 5   509  2030         29          156 China                        20667
## 6   510  2030         30          604 Peru                         22078
## # ... with 4 more variables: urban_agglomeration <chr>, note <chr>,
## #   population_millions <dbl>, geometry <POINT [°]>

Looks like urban_agglomerations is a panel-data version of population of global cities, between 1950 and 2030.

Make a ggplot2 map

ggplot(urban_agglomerations) +
  geom_sf()

ggplot(world) +
  geom_sf()

ggplot() +
  geom_sf(data = world) +
  geom_sf(data = urban_agglomerations)

Move it over to tmap!

Single custom map

tm_shape(world) +
  tm_polygons() +
  tm_shape(urban_agglomerations) +
  tm_dots(size = "population_millions", title.size = "Population (m)", col = "red")

Map with small multiples

tm_shape(world) +
  tm_polygons() +
  tm_shape(urban_agglomerations) +
  tm_dots(size = "population_millions", title.size = "Population (m)", col = "red") +
  tm_facets(by = "year")

Map (animated!!)

tm <- tm_shape(world) +
  tm_polygons() +
  tm_shape(urban_agglomerations) +
  tm_dots(size = "population_millions", title.size = "Population (m)", col = "red") +
  tm_facets(along = "year", free.coords = FALSE)

tmap_animation(tm, "city-pop-anim.gif", loop = TRUE, delay = 80)
## Animation saved to /Users/angela/Desktop/Spatial Data Science/workshop-scripts/doc/city-pop-anim.gif
magick::image_read("city-pop-anim.gif")